﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.OleDb;
using System.Text.RegularExpressions;

namespace Comercia
{
    public partial class form : Form
    {
        OleDbConnection conexion = null;
        List<Producto> lstProductos;
        List<Servicio> lstServicios;
        public form()
        {
            InitializeComponent();
            VaciarFormulario();
            CargarElementos();
            this.lstBoxServicios.DataSource = lstServicios;
            this.lstBoxServicios.ClearSelected();
            this.lstBoxProductos.DataSource = lstProductos;
            this.lstBoxProductos.ClearSelected();
            this.Identificadorlbl.Text = string.Empty;
            this.Nombrelbl.Text = string.Empty;
            this.Descripcionlbl.Text = string.Empty;
            this.Preciolbl.Text = string.Empty;
            this.Descuentolbl.Text = string.Empty;
            this.Impuestoslbl.Text = string.Empty;
            this.Empaquelbl.Text = string.Empty;
            this.Pesolbl.Text = string.Empty;
            this.Colorlbl.Text = string.Empty;
            this.Tamaniolbl.Text = string.Empty;
        }
        private void CargarElementos()
        {
            lstProductos = new List<Producto>();
            lstServicios = new List<Servicio>();
            ConectarBase();

            OleDbCommand cmd = conexion.CreateCommand();
            cmd.CommandText = "SELECT * FROM Producto ";


            OleDbDataReader dr = cmd.ExecuteReader();

            while (dr.Read())
            {
                try
                {
                    Producto p = new Producto();
                    p.Identificador = int.Parse(dr["Identificacion"].ToString());
                    p.Nombre = dr["Nombre"].ToString();
                    p.Descripcion = dr["Descripcion"].ToString();
                    p.Precio = int.Parse(dr["Precio"].ToString());
                    p.Descuentos = int.Parse(dr["Descuento"].ToString());
                    p.Impuestos = int.Parse(dr["Impuesto"].ToString());
                    p.Empaque = dr["Empaque"].ToString();
                    p.Peso = long.Parse(dr["Peso"].ToString());
                    p.Color = dr["Color"].ToString();
                    p.tamanio = double.Parse(dr["Tamanio"].ToString());
                    lstProductos.Add(p);
                }
                catch (Exception) { }
            }
            dr.Close();

            cmd = conexion.CreateCommand();
            cmd.CommandText = "SELECT * FROM Servicio ";


            dr = cmd.ExecuteReader();

            while (dr.Read())
            {
                try
                {
                    Servicio s = new Servicio();
                    s.Identificador = int.Parse(dr["Identificacion"].ToString());
                    s.Nombre = dr["Nombre"].ToString();
                    s.Descripcion = dr["Descripcion"].ToString();
                    s.Precio = int.Parse(dr["Precio"].ToString());
                    s.Descuentos = int.Parse(dr["Descuento"].ToString());
                    s.Impuestos = int.Parse(dr["Impuesto"].ToString());
                    lstServicios.Add(s);
                }
                catch (Exception) { }
            }
            dr.Close();
            DesconectarBase();

        }
        private void btnIngresar_Click(object sender, EventArgs e)
        {
            try
            {
                lblError.Text = "";

                noVacio("Identificador", txtIdentificador.Text);
                //numericoValido("Identificador", txtIdentificador.Text, 4);
                identificadorValido(txtIdentificador.Text);
                int identificador = int.Parse(txtIdentificador.Text);

                stringValido("Nombre", txtNombre.Text, 10);
                string nombre = string.IsNullOrEmpty(txtNombre.Text) ? "" : txtNombre.Text.Trim();
                soloLetrasYNum("Nombre", nombre);

                stringValido("Descripción", rchDescripcion.Text, 250);
                string descripcion = string.IsNullOrEmpty(rchDescripcion.Text) ? "" : rchDescripcion.Text.Trim();
                soloLetrasYNum("Descripción", descripcion);

                int precio = numericoValido("Precio", txtPrecio.Text, 5);
                numericoNoNegativo("Precio", precio);
                int desuentos = porcentajeValido(txtDescuentos.Text);
                int impuestos = numericoValido("Impuestos", txtImpuestos.Text, 3);
                numericoNoNegativo("Impuestos", impuestos);

                if (cmbProdServicio.SelectedItem.ToString() == "Producto")
                {
                    double tamanio = doubleValido("Tamaño", txtTamanio.Text, 8);
                    int peso = numericoValidoRango("Peso", txtPeso.Text, 1000);
                    numericoNoNegativo("Precio", peso);
                    numericoNoNegativo("Peso", impuestos);
                    string color = "";
                    if (radioBlanco.Checked) color = "Blanco";
                    if (radioRojo.Checked) color = "Rojo";
                    if (radioNegro.Checked) color = "Negro";
                    if (radioVerde.Checked) color = "Verde";
                    string empaque = rchEmpaque.Text;
                    soloLetrasYNum("Empaque", empaque);
                }

                DesHabilitarControles();
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
                lblError.ForeColor = Color.Red;
            }
        }

        private void DesHabilitarControles()
        {
            txtIdentificador.Enabled = false;
            txtNombre.Enabled = false;
            rchDescripcion.Enabled = false;
            txtPrecio.Enabled = false;
            txtDescuentos.Enabled = false;
            txtImpuestos.Enabled = false;
            cmbProdServicio.Enabled = false;
            txtTamanio.Enabled = false;
            txtPeso.Enabled = false;
            grpColores.Enabled = false;
            rchEmpaque.Enabled = false;

            btnIngresar.Visible = false;
            btnConfirmar.Visible = true;
            btnCancelar.Visible = true;
        }

        private void HabilitarControles()
        {
            txtIdentificador.Enabled = true;
            txtNombre.Enabled = true;
            rchDescripcion.Enabled = true;
            txtPrecio.Enabled = true;
            txtDescuentos.Enabled = true;
            txtImpuestos.Enabled = true;
            cmbProdServicio.Enabled = true;

            switch (cmbProdServicio.SelectedItem.ToString())
            {
                case "Producto":
                    {
                        txtTamanio.Enabled = true;
                        txtPeso.Enabled = true;
                        grpColores.Enabled = true;
                        rchEmpaque.Enabled = true;
                        break;
                    }
                case "Servicio":
                    {
                        txtTamanio.Enabled = false;
                        txtPeso.Enabled = false;
                        grpColores.Enabled = false;
                        rchEmpaque.Enabled = false;
                        break;
                    }
            }
            btnIngresar.Visible = true;
            btnConfirmar.Visible = false;
            btnCancelar.Visible = false;
        }


        #region Validations
        private void soloLetrasYNum(string field, string value)
        {
            Regex objAlphaNumericPattern = new Regex("[^a-zA-Z0-9]");
            bool valido = !objAlphaNumericPattern.IsMatch(value);
            if (!valido)
            {
                throw new Exception("Caracteres no permitidos en campo " + field);
            }
        }

        private int numericoValidoRango(string field, string value, int maxValue)
        {
            int resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (int.TryParse(value, out resultado))
            {
                if (resultado > maxValue)
                {
                    throw new Exception(field + " fuera de rango");
                }
                return resultado;
            }
            else
                throw new Exception(field + " no válido, debe ser numérico");
        }

        private bool stringValido(string field, string value, int maxLength)
        {
            if (!string.IsNullOrEmpty(value))
            {
                if (value.Trim().Length > maxLength)
                    throw new Exception(field + " excede tamaño permitido.");
            }
            return true;
        }

        private void noVacio(string field, string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                throw new Exception(field + " es campo obligatorio");
            }
            if (string.IsNullOrEmpty(value.Trim()))
            {
                throw new Exception(field + " es campo obligatorio");
            }
        }

        private bool identificadorValido(string field)
        {
            int value = 0;
            if (int.TryParse(field, out value))
            {
                if (value.ToString().Length != 4)
                {
                    throw new Exception("El Identificador debe ser de 4 digitos");
                }

                if (ConectarBase())
                {
                    OleDbCommand cmd = conexion.CreateCommand();
                    cmd.CommandText = "SELECT * FROM Producto P, Servicio S WHERE P.Identificacion = @ID or S.Identificacion = @ID";
                    cmd.Parameters.Add("@ID", field.Trim());

                    OleDbDataReader dr = cmd.ExecuteReader();

                    bool ret = true;

                    if (dr.Read())
                        throw new Exception("Identificador existente, ingrese otro");

                    dr.Close();
                    DesconectarBase();
                    return ret;
                }
                else
                    throw new Exception("Error de conexion a BD");
            }
            else
                throw new Exception("Identificador no válido, debe ser numérico");
        }

        private int numericoValido(string field, string value, int maxLength)
        {
            int resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (int.TryParse(value, out resultado))
            {
                if (resultado.ToString().Length > maxLength)
                {
                    throw new Exception(field + " fuera de rango");
                }
                return resultado;
            }
            else
                throw new Exception(field + " no válido, debe ser numérico");
        }

        private double doubleValido(string field, string value, int maxValue)
        {
            double resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (double.TryParse(value, out resultado))
            {
                if (resultado < 0)
                    throw new Exception(field + " debe ser mayor o igual a cero");

                if (resultado > maxValue)
                {
                        throw new Exception(field + " fuera de rango 0 - 8");
                }
               
                return resultado;
            }
            else
                throw new Exception(field + " no válido, debe ser numérico");
        }


        private bool numericoNoNegativo(string field, long value)
        {
            if (value < 0)
            {
                throw new Exception(field + " debe ser mayor o igual a cero");
            }
            return true;
        }

        private int porcentajeValido(string value)
        {
            int resultado = 0;

            if (string.IsNullOrEmpty(value))
                return 0;

            if (string.IsNullOrEmpty(value.Trim()))
                return 0;

            if (int.TryParse(value, out resultado))
            {
                if ((resultado < 0) || (resultado > 100))
                {
                    throw new Exception("Descuento no válido, debe estar en el rango 0 - 100");
                }
                else
                    return resultado;
            }
            else
                throw new Exception("Descuento no válido, debe ser numérico");
        }
        #endregion

        #region DataBase Functions
        private bool ConectarBase()
        {
            if (conexion == null)
            {
                conexion = new System.Data.OleDb.OleDbConnection();
                string source = Application.StartupPath + "\\BD\\Comercia.accdb";
                conexion.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + source + ";Persist Security Info=False;";
                conexion.Open();
            }
            return true;
        }

        private bool DesconectarBase()
        {
            if (conexion != null)
            {
                conexion.Close();
                conexion = null;
            }
            return true;
        }
        #endregion

        private bool AltaProducto(Producto prod)
        {
            if (ConectarBase())
            {
                OleDbCommand cmd = conexion.CreateCommand();
                cmd.CommandText = "INSERT INTO Producto VALUES (@Identificacion, @Nombre, @Descripcion, @Precio, @Descuento, @Impuesto, @Empaque, @Peso, @Color, @Tamanio)";
                cmd.Parameters.AddWithValue("@Identificacion", prod.Identificador);
                cmd.Parameters.AddWithValue("@Nombre", prod.Nombre);
                cmd.Parameters.AddWithValue("@Descripcion", prod.Descripcion);
                cmd.Parameters.AddWithValue("@Precio", prod.Precio);
                cmd.Parameters.AddWithValue("@Descuento", prod.Descuentos);
                cmd.Parameters.AddWithValue("@Impuesto", prod.Impuestos);
                cmd.Parameters.AddWithValue("@Empaque", prod.Empaque);
                cmd.Parameters.AddWithValue("@Peso", prod.Peso);
                cmd.Parameters.AddWithValue("@Color", prod.Color);
                cmd.Parameters.AddWithValue("@Tamanio", prod.tamanio);

                int result = cmd.ExecuteNonQuery();
                DesconectarBase();

                if (result != 1)
                    throw new Exception("Error al ingresar producto");
                else
                {
                    lstProductos.Add(prod);
                    this.lstBoxProductos.DataSource = null;
                    this.lstBoxProductos.Items.Clear();
                    this.lstBoxProductos.DataSource = lstProductos;
                    this.lstBoxProductos.ClearSelected();
                    return true;
                }
            }
            else
                throw new Exception("Error de conexion a BD");
        }

        private bool AltaServicio(Servicio serv)
        {
            if (ConectarBase())
            {
                OleDbCommand cmd = conexion.CreateCommand();
                cmd.CommandText = "INSERT INTO Servicio VALUES (@Identificacion, @Nombre, @Descripcion, @Precio, @Descuento, @Impuesto)";
                cmd.Parameters.AddWithValue("@Identificacion", serv.Identificador);
                cmd.Parameters.AddWithValue("@Nombre", serv.Nombre);
                cmd.Parameters.AddWithValue("@Descripcion", serv.Descripcion);
                cmd.Parameters.AddWithValue("@Precio", serv.Precio);
                cmd.Parameters.AddWithValue("@Descuento", serv.Descuentos);
                cmd.Parameters.AddWithValue("@Impuesto", serv.Impuestos);

                int result = cmd.ExecuteNonQuery();
                DesconectarBase();

                if (result != 1)
                    throw new Exception("Error al ingresar servicio");
                else
                {
                    lstServicios.Add(serv);
                    this.lstBoxServicios.DataSource = null;
                    this.lstBoxServicios.Items.Clear();
                    this.lstBoxServicios.DataSource = lstServicios;
                    this.lstBoxServicios.ClearSelected();
                    return true;
                }
            }
            else
                throw new Exception("Error de conexion a BD");
        }


        private void btnConfirmar_Click(object sender, EventArgs e)
        {
            try
            {
                noVacio("Identificador", txtIdentificador.Text);
                numericoValido("Identificador", txtIdentificador.Text, 4);
                identificadorValido(txtIdentificador.Text);
                int identificador = int.Parse(txtIdentificador.Text);

                stringValido("Nombre", txtNombre.Text, 10);
                string nombre = string.IsNullOrEmpty(txtNombre.Text) ? "" : txtNombre.Text.Trim();

                stringValido("Descripción", rchDescripcion.Text, 10);
                string descripcion = string.IsNullOrEmpty(rchDescripcion.Text) ? "" : rchDescripcion.Text.Trim();

                int precio = numericoValido("Precio", txtPrecio.Text, 5);
                int desuentos = porcentajeValido(txtDescuentos.Text);
                int impuestos = numericoValido("Impuestos", txtImpuestos.Text, 3);


                switch (cmbProdServicio.SelectedItem.ToString())
                {
                    case "Producto":
                        {
                            double tamanio = doubleValido("Tamaño", txtPeso.Text, 8);
                            int peso = numericoValidoRango("Peso", txtPeso.Text, 1000);
                            string color = "";
                            if (radioBlanco.Checked) color = "Blanco";
                            if (radioRojo.Checked) color = "Rojo";
                            if (radioNegro.Checked) color = "Negro";
                            if (radioVerde.Checked) color = "Verde";
                            string empaque = rchEmpaque.Text;

                            Producto prod = new Producto();
                            prod.Identificador = identificador;
                            prod.Nombre = nombre;
                            prod.Descripcion = descripcion;
                            prod.Precio = precio;
                            prod.Descuentos = desuentos;
                            prod.Impuestos = impuestos;
                            prod.Empaque = empaque;
                            prod.Peso = peso;
                            prod.Color = color;
                            prod.tamanio = tamanio;

                            AltaProducto(prod);
                            break;
                        }
                    case "Servicio":
                        {
                            Servicio serv = new Servicio();
                            serv.Identificador = identificador;
                            serv.Nombre = nombre;
                            serv.Descripcion = descripcion;
                            serv.Precio = precio;
                            serv.Descuentos = desuentos;
                            serv.Impuestos = impuestos;

                            AltaServicio(serv);
                            break;
                        }
                }

                lblError.Text = cmbProdServicio.SelectedItem.ToString() + " ingresado";
                lblError.ForeColor = Color.Green;

                VaciarFormulario();
                HabilitarControles();
            }
            catch (Exception ex)
            {
                lblError.Text = ex.Message;
                lblError.ForeColor = Color.Red;
            }
        }

        private void VaciarFormulario()
        {
            txtIdentificador.Text = string.Empty;
            txtNombre.Text = string.Empty;
            rchDescripcion.Text = string.Empty;
            txtPrecio.Text = string.Empty;
            txtDescuentos.Text = string.Empty;
            txtImpuestos.Text = string.Empty;
            cmbProdServicio.SelectedItem = "Servicio";

            txtTamanio.Text = string.Empty;
            txtTamanio.Enabled = false;

            txtPeso.Text = string.Empty;
            txtPeso.Enabled = false;

            grpColores.Enabled = false;

            rchEmpaque.Text = string.Empty;
            rchEmpaque.Enabled = false;
        }

        private void btnCancelar_Click(object sender, EventArgs e)
        {
            HabilitarControles();
        }

        private void cmbProdServicio_SelectedValueChanged(object sender, EventArgs e)
        {
            switch (cmbProdServicio.SelectedItem.ToString())
            {
                case "Producto":
                    {
                        txtTamanio.Enabled = true;
                        txtPeso.Enabled = true;
                        grpColores.Enabled = true;
                        rchEmpaque.Enabled = true;
                        break;
                    }
                case "Servicio":
                    {
                        txtTamanio.Text = string.Empty;
                        txtTamanio.Enabled = false;

                        txtPeso.Text = string.Empty;
                        txtPeso.Enabled = false;
                        grpColores.Enabled = false;

                        rchEmpaque.Text = string.Empty;
                        rchEmpaque.Enabled = false;
                        break;
                    }
            }
        }


        private void lstBoxProductos_SelectedValueChanged(object sender, EventArgs e)
        {
            if (lstBoxProductos.SelectedItem != null)
            {
                Producto prod = (Producto)lstBoxProductos.SelectedItem;
                this.Identificadorlbl.Text = prod.Identificador.ToString();
                this.Nombrelbl.Text = prod.Nombre;
                this.Descripcionlbl.Text = prod.Descripcion;
                this.Preciolbl.Text = prod.Precio.ToString();
                this.Descuentolbl.Text = prod.Descuentos.ToString();
                this.Impuestoslbl.Text = prod.Impuestos.ToString();
                this.Empaquelbl.Text = prod.Empaque;
                this.Pesolbl.Text = prod.Peso.ToString();
                this.Colorlbl.Text = prod.Color;
                this.Tamaniolbl.Text = prod.tamanio.ToString();
            }
        }

        private void lstBoxServicios_SelectedValueChanged(object sender, EventArgs e)
        {
            if (lstBoxServicios.SelectedItem != null)
            {
                Servicio serv = (Servicio)lstBoxServicios.SelectedItem;
                this.Identificadorlbl.Text = serv.Identificador.ToString();
                this.Nombrelbl.Text = serv.Nombre;
                this.Descripcionlbl.Text = serv.Descripcion;
                this.Preciolbl.Text = serv.Precio.ToString();
                this.Descuentolbl.Text = serv.Descuentos.ToString();
                this.Impuestoslbl.Text = serv.Impuestos.ToString();
                this.Empaquelbl.Text = string.Empty;
                this.Pesolbl.Text = string.Empty;
                this.Colorlbl.Text = string.Empty;
                this.Tamaniolbl.Text = string.Empty;
            }
        }
    }
}
